package cn.wonhigh.o2o.openfire.plugins.util;

import org.apache.commons.lang.StringUtils;
import org.jivesoftware.openfire.MessageRouter;
import org.jivesoftware.openfire.OfflineMessageStore;
import org.jivesoftware.openfire.PresenceManager;
import org.jivesoftware.openfire.user.User;
import org.jivesoftware.openfire.user.UserManager;
import org.jivesoftware.openfire.user.UserNotFoundException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xmpp.packet.JID;
import org.xmpp.packet.Message;
import org.xmpp.packet.Presence;

/**
 * 消息回执处理命令
 * 
 * @author wei.ss
 * @date 2016-03-09 上午10:38:43
 * @version 1.0.0 
 * @copyright wonhigh.net.cn 
 */
public class MessageReceiptCommand implements Runnable {
	
	private static final Logger LOG = LoggerFactory.getLogger(MessageReceiptCommand.class);
	
	private MessageRouter messageRouter;
	private PresenceManager presenceManager;
	private UserManager userManager;
	private OfflineMessageStore offlineMessageStore;
	private RedisTemplate redisTemplate;
	private Message message;
	
	public MessageReceiptCommand(MessageRouter messageRouter, PresenceManager presenceManager,
			OfflineMessageStore offlineMessageStore, UserManager userManager,
			RedisTemplate redisTemplate, Message message) {
		super();
		this.messageRouter = messageRouter;
		this.presenceManager = presenceManager;
		this.offlineMessageStore = offlineMessageStore;
		this.userManager = userManager;
		this.redisTemplate = redisTemplate;
		this.message = message;
	}

	@Override
	public void run() {
		try {
			String id = message.getID();
			JID targetJID = message.getTo();
			String key = MessageReceiptConstants.getMessageIdKey(id);
			if(redisTemplate.exists(key)) {// 收到回执，不需要继续处理
				redisTemplate.del(key);
				LOG.info("已经收到消息");
			} else { // 没有收到回执。判断用户状态：在线就重发，不在线就存入离线表
				Presence presence = getPresence(targetJID);
				
				String resendCountKey = MessageReceiptConstants.getMessageResendCountKey(id);
				String resendCountStr = redisTemplate.get(resendCountKey);
				int resendCount = 0;
				if(StringUtils.isNotBlank(resendCountStr)){
					resendCount = Integer.valueOf(resendCountStr);
				}
				redisTemplate.setex(resendCountKey, (resendCount+1)+"", 
						MessageReceiptConstants.MESSAGE_RE_SEND_KEY_CACHE_TIME);
				
				if(resendCount < MessageReceiptConstants.MESSAGE_RE_SEND_MAX_NUM 
						&& null != presence && presence.isAvailable()){ // 用户在线就重发
					messageRouter.route(message);
					LOG.info("没收到回执，重新转发消息");
				} else {// 用户不在线，存入离线表
					redisTemplate.del(resendCountKey);
					offlineMessageStore.addMessage2(message);
					LOG.info("用户不在线，把消息存入离线表");
				}
			}
		} catch (Exception e) {
			LOG.error("处理超时消息发生异常", e);
		}
	}
	
	/**
	 * 获取用户的在线状态
	 * 
	 * @param targetJID
	 * @return
	 * @throws UserNotFoundException
	 */
    private Presence getPresence(JID targetJID) throws UserNotFoundException {
    	Presence presence = null;
    	try {
    		String username = targetJID.getNode();
    		LOG.info("获取用户的在线状态:username={}", username);
			User user = userManager.getUser(targetJID.getNode());
			presence = presenceManager.getPresence(user);
		} catch (Exception e) {
			LOG.error("获取用户在线状态发生异常", e);
		}
    	return presence;
    }
}
